{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ljaxmsyEvTSW"
      },
      "outputs": [],
      "source": [
        "import yfinance as yf\n",
        "btc_ticker = yf.Ticker(\"BTC-USD\")\n",
        "btc_data = btc_ticker.history(period=\"max\")"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "btc_data"
      ],
      "metadata": {
        "id": "l8Lazi7cvZFG"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from matplotlib import pyplot as plt\n",
        "plt.plot(btc_data.Close)\n",
        "plt.show()"
      ],
      "metadata": {
        "id": "PgxAcnTCveOA"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "btc_data[\"moving_average\"] = btc_data[\"Close\"].rolling(10).mean()\n"
      ],
      "metadata": {
        "id": "Ni8xqugVvgrD"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "btc_data[['Close','moving_average']].plot()\n"
      ],
      "metadata": {
        "id": "15bwTQOHvh--"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from sklearn.metrics import mean_squared_error\n",
        "\n",
        "mean_squared_error(btc_data[\"Close\"][9:], btc_data[\"moving_average\"][9:])\n"
      ],
      "metadata": {
        "id": "pUyIxPkOvjnx"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "dataset_x = []\n",
        "dataset_y = []\n",
        "for j in range(0, 30):\n",
        "    for i in range(j, btc_data.shape[0], 31):\n",
        "        if btc_data[i : i + 31].Close.shape[0] == 31:\n",
        "            dataset_y.append(\n",
        "                1\n",
        "                if btc_data[i : i + 30].Close.mean() < btc_data.iloc[i + 30].Close\n",
        "                else 0\n",
        "            )\n",
        "        mean_ = btc_data[i : i + 30].Close.mean()\n",
        "        std_ = btc_data[i : i + 30].Close.std()\n",
        "        dataset_x.append(list((btc_data[i : i + 30].Close - mean_) / std_))\n"
      ],
      "metadata": {
        "id": "thA4Xlkvvm-O"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "import numpy as np\n",
        "dataset_x = np.array(dataset_x)\n",
        "dataset_y = np.array(dataset_y)\n",
        "And respectively, create train and test sets:\n",
        "train_x, test_x = dataset_x[:3000], dataset_x[3000:]\n",
        "train_y, test_y = dataset_y[:3000], dataset_y[3000:]"
      ],
      "metadata": {
        "id": "0V-X8c57v43D"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def encoder(inputs, head_size, num_heads, feed_forward_dimension, dropout=0):\n",
        "    # Attention layer\n",
        "    x = layers.MultiHeadAttention(\n",
        "        key_dim=head_size, num_heads=num_heads, dropout=dropout\n",
        "    )(inputs, inputs)\n",
        "    x = layers.Dropout(dropout)(x)\n",
        "    x = layers.LayerNormalization(epsilon=1e-6)(x)\n",
        "    attention_result = x + inputs\n",
        "    # Convlution as feedforward\n",
        "    x = layers.Conv1D(filters=feed_forward_dimension, kernel_size=1, activation=\"relu\")(\n",
        "        attention_result\n",
        "    )\n",
        "    x = layers.Dropout(dropout)(x)\n",
        "    x = layers.Conv1D(filters=inputs.shape[-1], kernel_size=1)(x)\n",
        "    x = layers.LayerNormalization(epsilon=1e-6)(x)\n",
        "    return x + attention_result\n"
      ],
      "metadata": {
        "id": "MR0Ythldv7Jv"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def build_model(\n",
        "    input_size,\n",
        "    head_size,\n",
        "    num_heads,\n",
        "    ff_dim,\n",
        "    num_transformer_blocks,\n",
        "    dense_units,\n",
        "    dropout=0,\n",
        "    dense_dropout=0,\n",
        "):\n",
        "    inputs = keras.Input(shape=input_size)\n",
        "    x = inputs\n",
        "    for _ in range(num_transformer_blocks):\n",
        "        x = encoder(x, head_size, num_heads, ff_dim, dropout)\n",
        "        x = layers.GlobalAveragePooling1D(data_format=\"channels_first\")(x)\n",
        "    for d in dense_units:\n",
        "        x = layers.Dense(d, activation=\"relu\")(x)\n",
        "        x = layers.Dropout(dense_dropout)(x)\n",
        "    outputs = layers.Dense(n_classes, activation=\"softmax\")(x)\n",
        "    return keras.Model(inputs, outputs)\n"
      ],
      "metadata": {
        "id": "kWupKkBkv_vo"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model = build_model(\n",
        "    x_train.shape[1:],\n",
        "    head_size=256,\n",
        "    num_heads=4,\n",
        "    ff_dim=4,\n",
        "    dropout=0.25,\n",
        "    num_transformer_blocks=4,\n",
        "    dense_units=[128],\n",
        "    dense_dropout=0.4,\n",
        ")\n"
      ],
      "metadata": {
        "id": "x58Bj3y6wNLz"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model.compile(\n",
        "    loss=\"sparse_categorical_crossentropy\",\n",
        "    optimizer=keras.optimizers.Adam(learning_rate=1e-4),\n",
        "    metrics=[\"sparse_categorical_accuracy\"],\n",
        ")\n",
        "model.summary()\n"
      ],
      "metadata": {
        "id": "mPLvnpcxwQ6u"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "callbacks = [keras.callbacks.EarlyStopping(patience=5, restore_best_weights=True)]\n"
      ],
      "metadata": {
        "id": "YF4BI8XYwYFr"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model.fit(\n",
        "    x_train,\n",
        "    y_train,\n",
        "    epochs=5,\n",
        "    batch_size=64,\n",
        "    callbacks=callbacks,\n",
        ")\n"
      ],
      "metadata": {
        "id": "9FSb4zBNwcaI"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "model.evaluate(x_test, y_test, verbose=1)"
      ],
      "metadata": {
        "id": "PwXnuPLHwgEv"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}